/*
*Copyright (c) Nikhil Jain.
*Project ICARUS, communications and 
*artificial intelligence.
*/



package javadrone.client.simulator;

//~--- non-JDK imports --------------------------------------------------------

import simbad.demo.DemoManager;

import simbad.gui.AgentInspector;
import simbad.gui.WorldWindow;

import simbad.sim.*;

//~--- JDK imports ------------------------------------------------------------

//import javax.swing.UIManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.Console;

import java.util.ArrayList;

import javax.swing.*;

/**
 * This is the Simbad application mainframe.
 *
 */
public class ClientGUI extends JFrame implements ActionListener {
    static int                SIZEX             = 800;
    static int                SIZEY             = 700;
    static ClientGUI          clientGUIInstance = null;
    private static final long serialVersionUID  = 1L;
    static final String       version           = "1.4";
    AgentInspector            agentInspector    = null;
    Console                   console           = null;
    DisabledControlWindow     controlWindow     = null;
    WorldWindow               worldWindow       = null;
    boolean                   backgroundMode;
    JDesktopPane              desktop;
    JMenuBar                  menubar;
    Simulator                 simulator;
    World                     world;

    /** Construct ClientGUI application with the given environement description */
    public ClientGUI(EnvironmentDescription ed, boolean backgroundMode) {
        super("ClientGUI  - version " + version);
        clientGUIInstance   = ClientGUI.this;
        this.backgroundMode = backgroundMode;
        desktop             = new JDesktopPane();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(SIZEX, SIZEY);
        createGUI();
        start(ed);
        setVisible(true);
    }

    /** Create the main GUI. Only called once. */
    private void createGUI() {
        desktop.setFocusable(true);
        getContentPane().add(desktop);
        menubar = new JMenuBar();
        menubar.add(DemoManager.createMenu(this));
        setJMenuBar(menubar);
    }

    /** Starts (or Restarts after releaseRessources) the world and simulator. */
    private void start(EnvironmentDescription ed) {
        System.out.println("Starting environmentDescription: " + ed.getClass().getName());
        world     = new World(ed);
        simulator = new Simulator(desktop, world, ed);
        createInternalFrames();

        if (backgroundMode) {
            runBackgroundMode();
        }
    }

    /** Release all ressources. */
    private void releaseRessources() {
        simulator.dispose();
        world.dispose();
        disposeInternalFrames();
    }

    /**
     * Creates the windows as Swing InternalFrames
     */
    private void createInternalFrames() {
        worldWindow = new WorldWindow(world);
        desktop.add(worldWindow);
        worldWindow.show();
        worldWindow.setLocation(300, 20);
        agentInspector = createAgentInspector(simulator, 20, 20);

        if (!backgroundMode) {
            controlWindow = new DisabledControlWindow(world, simulator);
            desktop.add(controlWindow);
            controlWindow.show();
            controlWindow.setLocation(300, 450);
        }
    }

    /**
     * Dispose the windows- used before restart.
     */
    private void disposeInternalFrames() {
        simulator.dispose();
        worldWindow.dispose();

        if (agentInspector != null) {
            agentInspector.dispose();
        }

        if (controlWindow != null) {
            controlWindow.dispose();
        }
    }

    /**
     * creates agent inspector window
     */
    private AgentInspector createAgentInspector(Simulator simulator, int x, int y) {
        ArrayList   agents = simulator.getAgentList();
        SimpleAgent a      = ((SimpleAgent) agents.get(0));

        if (a instanceof Agent) {
            AgentInspector ai = new AgentInspector((Agent) a, !backgroundMode, simulator);

            desktop.add(ai);
            ai.show();
            ai.setLocation(x, y);

            return ai;
        } else {
            return null;
        }
    }

    public void actionPerformed(ActionEvent event) {
        if (event.getActionCommand() == "demo") {
            releaseRessources();
            start(DemoManager.getDemoFromActionEvent(event));
        }
    }

    /**
     * Runs Simbad in background mode for computation intensive application.
     * Minimize graphic display and renderer computation.
     */
    private void runBackgroundMode() {

        // TODO pb with collision , pb with camera in this mode.
        setTitle(this.getTitle() + " - Background Mode");
        System.out.println("---------------------------------------------");
        System.out.println("Simbad is running in 'Background Mode");
        System.out.println("World is rendered very rarely. UI is disabled");
        System.out.println("--------------------------------------------");

        // slow down
        agentInspector.setFramesPerSecond(0.5f);

        // Show a small indication window
        JInternalFrame frame = new JInternalFrame();
        JPanel         p     = new JPanel();

        p.add(new JLabel("BACKGROUND MODE"));
        frame.setContentPane(p);
        frame.setClosable(false);
        frame.pack();
        frame.setLocation(SIZEX / 2, SIZEY * 3 / 4);
        desktop.add(frame);
        frame.show();
        world.changeViewPoint(World.VIEW_FROM_TOP, null);

        // start
        simulator.startBackgroundMode();
    }

    public void startSimulation() {
        controlWindow.startSimulation();
    }

    /** The simbad main. Process command line arguments and launch simbad. */
    public static void main(String[] args) {

        // process options
        boolean backgroundMode = false;

        for (int i = 0; i < args.length; i++) {
            if ("-bg".compareTo(args[i]) == 0) {
                backgroundMode = true;
            }
        }

        // Check java3d presence
        try {
            Class.forName("javax.media.j3d.VirtualUniverse");
        } catch (ClassNotFoundException e1) {
            JOptionPane.showMessageDialog(null, "Simbad requires Java 3D", "Simbad 3D", JOptionPane.ERROR_MESSAGE);
            System.exit(-1);
        }

        // request antialising
        System.setProperty("j3d.implicitAntialiasing", "true");

        ClientGUI c = new ClientGUI(new simbad.demo.KheperaDemo(), backgroundMode);

        c.startSimulation();
    }

    public JDesktopPane getDesktopPane() {
        return desktop;
    }

    // ///////////////////////
    // Class methods
    public static ClientGUI getSimbadInstance() {
        return clientGUIInstance;
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
